<template>
  <vxe-toolbar ref="toolbarRef">
    <template #tools>
      <slot name="otherTools"></slot>
      <template v-for="item in toolbarButtons" :key="item.code">
        <el-button
          v-if="item.visible"
          @click="() => buttonClickEvent(item)"
          class="shanshu-btn-reset-icon"
          :type="item.status"
        >
          <Icon :icon="`svg-icon:${item.icon}`" :size="16" />{{ item.name }}</el-button
        >
      </template>
    </template>
    <template #buttons>
      <el-tooltip content="全屏切换" v-if="showScrennfull" placement="top">
        <el-button @click="clickScreenfull" class="shanshu-custom">
          <Icon v-show="isFull" icon="svg-icon:icon-hua-screenfull-putaway" :size="16" />
          <Icon v-show="!isFull" icon="svg-icon:icon-hua-screenfull-spread" :size="16"
        /></el-button>
      </el-tooltip>
      <el-tooltip content="列设置" placement="top">
        <el-button @click="clickCustomEvent" class="shanshu-custom" v-if="showCustom">
          <Icon icon="svg-icon:icon-hua-set" :size="16"
        /></el-button>
      </el-tooltip>
    </template>
    <template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="scope">
      <slot :name="slotName" v-bind="scope"></slot>
    </template>
  </vxe-toolbar>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { VxeUI, VxeToolbarInstance } from 'vxe-table'
import type { IVxeTableBtnsProps } from '../../types'
// 自定义按钮操作 https://vxetable.cn/#/component/table/toolbar/template/buttons
interface prop {
  tableRef: any
  tableData: any
  changeButtonsVisible: Function
  batchEditSuccess: Function // 批量编辑成功回调
  deleteBatch: Function // 批量删除事件
  leftBtns: IVxeTableBtnsProps // 左侧按钮显示设置， 传入 false 则不显示按钮， 默认显示全部 ， 传入字符串数组 指定显示 ['add','import']
  exportHandler: Function // 导出按钮事件
  importHandler: Function // 导入按钮事件
  showCustom: boolean // 是否需要右侧操作栏 列设置
  editAssign: any // 合并行中的值
  deleteAllHandler: () => void // 批量删除全部事件
  screenfullHandler: () => void
  addCallback?: (params?: any) => void
  showScrennfull: boolean
  otherBtns: any
  isFull: boolean
}
// 🌟组件props的ts定义必须在组件中声明
const props = withDefaults(defineProps<Partial<prop>>(), {
  tableRef: {},
  changeButtonsVisible: () => {},
  deleteBatch: () => {},
  exportHandler: () => {},
  importHandler: () => {},
  batchEditSuccess: () => {},
  tableData: [],
  leftBtns: true,
  showCustom: true,
  isFull: false,
  editAssign: {},
  screenfullHandler: () => {},
  showScrennfull: true,
  otherBtns: []
})
const toolbarRef = ref<VxeToolbarInstance>()
let toolbarButtons = reactive<any>([
  // https://vxeui.com/#/component/icon/base 图标列表 icon
  { name: '保存', code: 'save', status: '', visible: false, icon: 'icon-hua-save' },
  { name: '取消', code: 'cancel', status: '', visible: false, icon: 'icon-hua-cancel' },
  { name: '批量删除', code: 'editDel', status: '', visible: true, icon: 'icon-hua-batch-delete' },
  { name: '批量编辑', code: 'editBatch', status: '', visible: true, icon: 'icon-hua-batch-edit' },
  { name: '导入', code: 'import', status: '', visible: true, icon: 'icon-hua-import' },
  { name: '导出', code: 'export', status: '', visible: true, icon: 'icon-hua-export' },
  { name: '新增', code: 'add', status: 'primary', visible: true, icon: 'icon-hua-add' }
])

const clickScreenfull = () => {
  props.screenfullHandler()
}

// 初始化按钮配置
const initBtnHandler = (list: IVxeTableBtnsProps) => {
  toolbarButtons.unshift(...props.otherBtns)
  if (list === true) return
  if (list === false) {
    toolbarButtons = []
    return
  }
  toolbarButtons = toolbarButtons.filter((item: any) => list.includes(item.code))
}

// 初始化按钮数据
initBtnHandler(props.leftBtns)
// 插入一行， 页面更新或分页查询等失效
const insertEvent = async (row?: any | number) => {
  const $table = props.tableRef
  if ($table) {
    const insertRecords = $table.getInsertRecords() // 获取新增项
    if (insertRecords.length === 1) {
      VxeUI.modal.message({
        content: `请先保存上一条新增的数据`,
        status: 'error'
      })
      return
    }
    const record = {}
    const { row: newRow } = await $table.insertAt(record, row)
    // 获取到可编辑项里面的 第一个 key 设置成新增以后就可编辑状态
    const arr = $table.getColumns()
    const editList = arr
      .filter((item) => item.field && item?.editRender?.enabled !== false)
      .map((item) => item.field)
    const addParams = {} as any
    // 默认增量参数， 如 创建时间，创建人，不允许编辑， 需要赋值
    // if (arr.some((item) => item.field === 'createTime')) {
    //   addParams.createTime = Date.now()
    // }
    // if (arr.some((item) => item.field === 'createBy')) {
    //   addParams.createBy = userStore.user.nickname
    // }
    // assign 合并行 当中的固定值 如一些不可编辑的选项
    await $table.setEditCell(Object.assign(newRow, props.editAssign, addParams), editList[0])
  }
}
// 批量编辑的保存 + 校验
const saveHandler = async () => {
  const $table = props.tableRef
  if ($table) {
    const updateRecords = $table.getUpdateRecords()
    // 校验表格所有行的数据
    const errMap = await $table.fullValidate(updateRecords) // updateRecords 校验变动的数据，  传 true ， 校验所有数据
    if (errMap) {
      VxeUI.modal.message({
        content: `请检查填写的数据`,
        status: 'error'
      })
      return
    }
    if (updateRecords.length === 0) {
      VxeUI.modal.message({
        content: `没有改动过的数据`,
        status: 'error'
      })
      return
    }
    props?.batchEditSuccess(updateRecords)
  }
}
// bool true 打开批量编辑   fasle 取消批量编辑
const changeButtonsVisible = (bool: boolean) => {
  const $table = props.tableRef
  if (bool) {
    // 删除没有保存的新增项
    const insertRecords = $table.getInsertRecords()
    if (insertRecords.length !== 0) {
      $table.remove(insertRecords[0])
    }
  }
  props.changeButtonsVisible()
  toolbarButtons.map((item) => (item.visible = !item.visible))
}

const buttonClickEvent: any = ({ code }) => {
  const $table = props.tableRef
  const selectRecords = $table.getCheckboxRecords()
  const insertLoad = $table.getInsertRecords()

  switch (code) {
    case 'add':
      if (props?.addCallback) {
        props.addCallback()
      } else {
        insertEvent()
      }
      return
    case 'editBatch':
      changeButtonsVisible(true)
      return
    case 'cancel':
      if ($table) {
        $table.clearEdit().then(() => {
          // 还原数据
          $table.revertData()
        })
      }
      changeButtonsVisible(false)
      return
    case 'save':
      saveHandler()
      return
    case 'editDel':
      const { data } = $table // 获取当前列表数据， 没有数据无需删除
      if (data.length === 0) {
        VxeUI.modal.message({
          content: `当前没有数据可以删除!`,
          status: 'error'
        })
        return
      }
      // 批量删除 ，如果没有选中项提示一下
      if ($table && props.deleteBatch) {
        if (selectRecords.length === 0) {
          VxeUI.modal.confirm({
            className: 'common-dialog-rest',
            content: `确认删除全部数据?`,
            onConfirm() {
              props.deleteBatch([])
            }
          })
          return
        }
        // 如果有新增没有保存的数据， 提示去保存
        if (insertLoad.length !== 0) {
          VxeUI.modal.message({
            content: `有新增的数据没有保存!`,
            status: 'error'
          })
          return
        }
        VxeUI.modal.confirm({
          className: 'common-dialog-rest',
          content: `确认删除${selectRecords.length}条数据?`,
          onConfirm() {
            props.deleteBatch(selectRecords)
          }
        })
      }
      return
    case 'export':
      props.exportHandler()
      return
    case 'import':
      props.importHandler()
      return
  }
  // 处理自定义按钮
  props.otherBtns.map((item) => {
    if (code === item.code) {
      if (selectRecords.length === 0) {
        VxeUI.modal.message({
          content: `请选择数据`,
          status: 'error'
        })
        return
      }
      if (insertLoad.length !== 0) {
        VxeUI.modal.message({
          content: `有新增的数据没有保存!`,
          status: 'error'
        })
        return
      }
      item.click(selectRecords)
    }
  })
}

// 自定义列设置按钮 组件中的 custom 删掉即可
const clickCustomEvent = () => {
  const $table = props.tableRef
  if ($table) {
    $table.openCustom()
  }
}
defineExpose({ toolbarRef })
</script>
<style lang="scss" scoped>
.vxe-toolbar {
  border-top-left-radius: 4px;
  border-top-right-radius: 4px;
}
.shanshu-custom {
  width: 32px;
  height: 32px;
  border-color: #c9d2e5;
}
</style>
